package model;

import org.jbox2d.common.Vec2;
import org.newdawn.slick.Color;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.geom.Polygon;
import org.newdawn.slick.geom.Shape;
import controller.Global;

public class WaterGlobal {

	int MAXX = 1000;
	int MAXY = 20;
	int DAMP = 256;

	float[][][] waveMap = new float[2][MAXX][MAXY];

	int CT = 0, NW = 1;
	long t = 0, t1 = 0;

	public WaterGlobal() {
	}

	public void update() {
		int x, y, Temporary_Value;
		float n;

		if (System.currentTimeMillis() > t) {
			t = System.currentTimeMillis() + 10;
		} else {
//			return;
		}

		// add constant waves
//		if (System.currentTimeMillis() > t1) {
//			t1 = System.currentTimeMillis() + 120;
//			int x1 = (int) (Math.random() * ((float) MAXX));
//			int y1 = (int) (Math.random() * ((float) MAXY));
//			
//			System.out.println(x1 + "," + y1);
//			waveMap[0][x1][y1] = -5;
//		}

		for (y = 1; y < MAXY - 1; y++) {

			for (x = 1; x < MAXX - 1; x++) {

				n = (float) ((waveMap[CT][x - 1][y] + waveMap[CT][x + 1][y]
						+ waveMap[CT][x][y - 1] + waveMap[CT][x][y + 1]) / 2 - waveMap[NW][x][y]);

				n = n - (n / DAMP);
				waveMap[NW][x][y] = n;
			}
		}
		Temporary_Value = CT;
		CT = NW;
		NW = Temporary_Value;
	}

	public void impact(float x, float f) {
		x = x + Global.worldSize;
		x /= (2 * Global.worldSize / MAXX);
		if (x > 0 && x < MAXX) {
			waveMap[0][(int) x][MAXY / 2] = -2 * f;
		}
	}

	public Shape getPolygon() {
		float mean, mean1, mx, my;
		Vec2 p = new Vec2(0, Global.waterLevel);
		Vec2 p1 = new Vec2(0, 0);
		Vec2 min = new Vec2(Global.screenToWorld(0, 0).x, 0);
		Vec2 max = new Vec2(Global.screenToWorld(Global.screenX, 0).x, 0);
		p = Global.worldToScreen(p.x, p.y);
		p.y = (p.y < 0) ? -5f : p.y;
		float sx = 1, numNodes = 0;
		Polygon poly = new Polygon();

		min.x -= 2f;
		max.x += 2f;

		// find out how many points are between min and max
		numNodes = (max.x - min.x) * 5;
		System.out.println("numnodes = " + numNodes);
		
		sx = numNodes / 50;
		if (sx < 1){
			sx = 1;
		}
		
		for (int x1 = 0; x1 < MAXX; x1+= sx) {
			mean = mean1 = 0;
			for (int y1 = 0; y1 < MAXY; y1++) {
				mean += waveMap[0][x1][y1];
			}
			for (int y1 = 0; y1 < MAXY; y1++) {
				mean1 += waveMap[0][x1][y1];
			}
			mean = mean / ((float) MAXY);
			mean1 = mean1 / ((float) MAXY);
			mean = (mean + mean1) / 2f;
			my = mean;
			mx = x1 - (MAXX / 2);
			mx *= Global.worldSize / (MAXX / 2);

			p1 = Global.worldToScreen(mx, my + Global.waterLevel);
			
			if (mx > min.x && mx < max.x) {
				poly.addPoint(p1.x, p1.y);
			}
		}
		poly.addPoint(Global.screenX, Global.screenY);
		poly.addPoint(0, Global.screenY);
		return poly;
	}

	public void render(Graphics g, Image image) {
		Vec2 p = new Vec2(0, Global.waterLevel);
		p = Global.worldToScreen(p.x, p.y);
		p.y = (p.y < 0) ? -5f : p.y;

		// draw water line for demo purposes only
		g.setColor(new Color(128, 128, 200));
		g.texture(getPolygon(), image);
	}
}
